import { defineStore } from 'pinia';
import { store } from '/@/plugins/setupStore';

import { LoginParams, GetUserInfoModel } from '../api/system/model/userModel';
import { login as loginApi, refreshToken as refreshTokenApi } from '/@/api/system/user';
import { router } from '/@/router';
import { PageEnum } from '/@/enums/pageEnum';

interface UserState {
  userInfo: UserInfo;
  token: string;
  tokenTime: number;
  refreshToken: string;
  sessionTimeout?: boolean;
  lastUpdateTime: number;
}

export const useUserStore = defineStore({
  id: 'app-user',
  state: (): UserState => ({
    // user info
    userInfo: {},
    // token
    token: '',
    tokenTime: 0,
    // refreshToken
    refreshToken: '',
    // Whether the login expired
    sessionTimeout: false,
    // Last fetch time
    lastUpdateTime: 0
  }),
  getters: {
    getUserInfo(): UserInfo {
      return this.userInfo;
    },
    getToken(): string {
      return this.token || localStorage.getItem('token') || '';
    },
    getRefreshToken(): string {
      return this.refreshToken || localStorage.getItem('refreshToken') || '';
    },
    getTokenTime(): number {
      return this.tokenTime;
    }
  },
  actions: {
    setToken(info: string) {
      this.token = info ? info : ''; // for null or undefined value
      const time = new Date().getTime();
      this.tokenTime = time;
      localStorage.setItem('token', info || '');
    },
    setRefreshToken(info: string) {
      this.refreshToken = info;
      localStorage.setItem('refreshToken', info || '');
    },
    setUserInfo(info: UserInfo) {
      this.userInfo = info;
      this.lastUpdateTime = new Date().getTime();
    },
    setSessionTimeout(flag: boolean) {
      this.sessionTimeout = flag;
    },
    //刷新token
    async refreshTokens() {
      const userInfo = this.userInfo;
      const data = await refreshTokenApi({
        grant_type: 'declare_refresh_token',
        scope: 'all',
        tenantId: userInfo.tenant_id,
        refresh_token: this.getRefreshToken
      });
      const { access_token, refresh_token } = data.data;
      const newUserInfo = data.data as any as UserInfo;
      this.setUserInfo(newUserInfo);
      // save token
      access_token && this.setToken(access_token);
      refresh_token && this.setRefreshToken(refresh_token);
    },
    resetState() {
      this.userInfo = {};
      this.token = '';
      this.refreshToken = '';
      this.tokenTime = 0;
      this.sessionTimeout = false;
    },
    /**
     * @description: login
     */
    async login(params: any): Promise<GetUserInfoModel | null> {
      try {
        const data = await loginApi(params);
        const { error_code, error_description, access_token, refresh_token } = data.data as any;
        if (error_code) {
          return Promise.reject({ response: { data: { msg: error_description } } });
        }

        // save token
        this.setToken(access_token);
        this.setRefreshToken(refresh_token);
        // get user info
        const userInfo = data as any as GetUserInfoModel;
        this.setUserInfo(userInfo);
        return userInfo;
      } catch (error) {
        return Promise.reject(error);
      }
    },
    logout(toLogin = false) {
      this.setToken('');
      this.setRefreshToken('');
      toLogin && router.push(PageEnum.BASE_HOME);
    }
  }
});

// Need to be used outside the setup
export function useUserStoreWithOut() {
  return useUserStore(store);
}
